/*
 * Copyright (c) 2006-2021, Halo team
 *
 * SPDX-License-Identifier: GPLv3
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-09-11     Eywen        the first version
 */

#include "temperature.h"
#include "common.h"
#include "drv_temprature.h"

static float temperature_get(temperature_t *device);

bool temperature_init(temperature_t *device, ...)
{
    ASSERT_NULL(device);
    ASSERT_NULL(device->temperautre_sensor);

    /* 根据不同传感器类型来送入温度传感器参数，初始化描述符 */
    switch (device->type)
    {
    case temperature_type_ntc:
        goto temperature_type_ntc_init;
        break;
    default:
        return false;
    }

/* 不同型号的初始化逻辑 */
temperature_type_ntc_init:                         /* NTC 类型的温度传感器初始化 */
    do{
        temperature_ntc_t *ntc;
        ntc = device->temperautre_sensor;

        const char *adc_dev_name;
        uint32_t adc_channle;
        uint8_t adc_bits;
        temperature_ntc_mode_t mode;
        uint32_t resistance_up;

        int ptr_size;
        ptr_size = sizeof(void *);
        va_list v1;
        va_start(v1, device);
        switch (ptr_size)
        {
        case 4: /*32 位 cpu*/
            adc_dev_name = (const char *)va_arg(v1, int);
            break;
        default:
            debug_faltal("The current code does not support this CPU");
            return false;
        }
        adc_channle = (uint32_t)va_arg(v1, int);
        adc_bits = (uint8_t)va_arg(v1, int);
        mode = (temperature_ntc_mode_t)va_arg(v1, int);
        resistance_up = (uint32_t)va_arg(v1, int);

        va_end(v1);

        /* 指定各参数 */
        if(ntc->ops->init(ntc, adc_dev_name, adc_channle, adc_bits, mode,
                         resistance_up) == true){
            debug_faltal("ntc temperature sensor init fail");
            return true;
        }
    }while(0);
    debug_info("ntc temperature sensor init success");
    return false;
}

temperature_ops_t s_temperature_ops = {
        .init = temperature_init,
        .temperature_get = temperature_get,
};

/* 按照温度传感器类型来注册温度结构体句柄 */
bool temperature_register(temperature_t *device, temperature_type_t type)
{
    ASSERT_NULL(device);

    MEM_MEMSET(device, 0, sizeof(temperature_t));

    /* 指定温度传感器类型 */
    device->type = type;

    device->ops = &s_temperature_ops;

    void *sensor_ptr;
    /* 注册具体的传感器型号 */
    switch (type)
    {
    case temperature_type_ntc: /* NTC 类型的温度传感器 */
        do{
            temperature_ntc_t *ntc_ptr;
            ntc_ptr = MEM_MALLOC(sizeof(temperature_ntc_t));
            if(ntc_ptr == NULL){
                debug_error("Insufficient system memory");
                return false;
            }
            ntc_ptr->ops = find_temerature_ops_by_mode(temperature_type_ntc);
            sensor_ptr = ntc_ptr;
        }while(0);
        break;
    default:
        debug_error("The current software version does not support this model of sensor(%d)", type);
        return false;
    }

    if(sensor_ptr == NULL){
        debug_error("Insufficient system memory");
        return false;
    }
    device->temperautre_sensor = sensor_ptr;
    debug_info("Temperature sensor(%u) registered successfully", type);
    return true;
}

static float temperature_get(temperature_t *device)
{
    ASSERT_NULL(device);
    ASSERT_NULL(device->ops);

    switch (device->type){
    case temperature_type_ntc: /* NTC 类型的温度传感器 */
        do{
            temperature_ntc_t *ntc_sensor;
            ntc_sensor = device->temperautre_sensor;
            return ntc_sensor->ops->temperature(ntc_sensor);
        }while(0);
        break;

    default :
        return (float)-UINT16_MAX;
    }
}

/* 创建一个温度传感器对象 */
temperature_t *temperature_create(temperature_type_t type)
{
    temperature_t *ptr;

    ptr = MEM_MALLOC(sizeof (temperature_t));
    if(NULL == ptr){
        goto err;
    }

    if(false == temperature_register(ptr, type)){
        goto err;
    }

    return ptr;
err:
    if(NULL != ptr){
        MEM_FREE(ptr);
    }
    return NULL;
}
